﻿using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Hp.Vertica.Migration.SqlServer
{
    public class ColumnCollection
    {
        public TableBase Table { get; set; }

        private Dictionary<String, Column> _columnsCache;

        public void Refresh()
        {
            Dictionary<String, Column> current = new Dictionary<string, Column>();
            using (SqlConnection conn = new SqlConnection(this.Table.Database.DataSource.ConnectionString))
            {
                conn.Open();
                conn.ChangeDatabase(this.Table.Database.Name);
                var cmd = conn.CreateCommand();
                cmd.CommandText = @"SELECT c.name
                                ,t.name AS type_name
                                ,c.max_length
                                ,c.precision
                                ,c.scale
                                ,c.is_nullable
                                ,c.is_identity
                                FROM sys.columns c
                                JOIN sys.objects o
                                ON c.object_id = o.object_id
                                JOIN sys.schemas s
                                ON o.schema_id = s.schema_id
                                JOIN sys.types t
                                ON c.system_type_id = t.system_type_id
                                AND c.user_type_id = t.user_type_id
                                WHERE s.name = @schemaName 
                                AND o.name = @objectName
                                ORDER BY c.column_id";
                using (var dr = cmd.ExecuteReader())
                {
                    while (dr.Read())
                    {
                        String name = dr["column_name"].ToString();
                        String key = name.ToUpper();
                        if (_columnsCache != null && _columnsCache.ContainsKey(key))
                        {
                            current.Add(key, _columnsCache[key]);
                        }
                        else
                        {
                            Column col = new Column();
                            col.Name = name;
                            col.IsIdentity = Boolean.Parse(dr["is_identity"].ToString());
                            col.IsNullable = Boolean.Parse(dr["is_nullable"].ToString());
                            var size = Int32.Parse(dr["max_length"].ToString());
                            var precision = Int32.Parse(dr["precision"].ToString());
                            var scale = Int32.Parse(dr["scale"].ToString());
                            col.DataType = SqlDataType.Create(dr["type_name"].ToString(), size, precision, scale);
                            current.Add(key, col);
                        }

                    }
                }
            }
            this._columnsCache = current;
        }

        public List<Column> Columns
        {
            get
            {
                if (this._columnsCache == null)
                {
                    this.Refresh();
                }
                return this._columnsCache.Values.ToList();
            }
        }
    }
}
